"""
控制面板组件模块

该模块实现了跟踪控制和参数设置界面。
主要功能：
1. 视频加载和播放控制
2. 跟踪开始/停止控制
3. 算法参数调整
4. 跟踪信息显示

作者：目标跟踪系统
日期：2024
"""

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from typing import Dict, Optional


class ControlPanel(QWidget):
    """
    控制面板类
    
    提供跟踪控制和参数设置的用户界面。
    """
    
    # 自定义信号
    load_video_clicked = pyqtSignal()
    start_tracking_clicked = pyqtSignal()
    stop_tracking_clicked = pyqtSignal()
    play_pause_clicked = pyqtSignal()
    parameters_changed = pyqtSignal(dict)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
        # 初始化界面
        self.init_ui()
        
        # 参数默认值
        self.default_params = {
            'similarity_threshold': 0.3,
            'max_lost_frames': 10,
            'kalman_weight': 0.3
        }
        
    def init_ui(self):
        """
        初始化用户界面
        """
        self.setFixedWidth(300)
        
        # 创建主布局
        main_layout = QVBoxLayout(self)
        
        # 创建各个功能组
        self.create_video_control_group()
        self.create_tracking_control_group()
        self.create_parameter_group()
        self.create_info_group()
        
        # 添加到主布局
        main_layout.addWidget(self.video_group)
        main_layout.addWidget(self.tracking_group)
        main_layout.addWidget(self.parameter_group)
        main_layout.addWidget(self.info_group)
        main_layout.addStretch()
        
    def create_video_control_group(self):
        """
        创建视频控制组
        """
        self.video_group = QGroupBox("视频控制")
        layout = QVBoxLayout(self.video_group)
        
        # 加载视频按钮
        self.load_video_btn = QPushButton("加载视频")
        self.load_video_btn.clicked.connect(self.load_video_clicked.emit)
        layout.addWidget(self.load_video_btn)
        
        # 播放/暂停按钮
        self.play_pause_btn = QPushButton("播放/暂停")
        self.play_pause_btn.clicked.connect(self.play_pause_clicked.emit)
        self.play_pause_btn.setEnabled(False)
        layout.addWidget(self.play_pause_btn)
        
        # 视频信息标签
        self.video_info_label = QLabel("未加载视频")
        self.video_info_label.setWordWrap(True)
        layout.addWidget(self.video_info_label)
        
    def create_tracking_control_group(self):
        """
        创建跟踪控制组
        """
        self.tracking_group = QGroupBox("跟踪控制")
        layout = QVBoxLayout(self.tracking_group)
        
        # 开始跟踪按钮
        self.start_tracking_btn = QPushButton("开始跟踪")
        self.start_tracking_btn.clicked.connect(self.start_tracking_clicked.emit)
        self.start_tracking_btn.setEnabled(False)
        layout.addWidget(self.start_tracking_btn)
        
        # 停止跟踪按钮
        self.stop_tracking_btn = QPushButton("停止跟踪")
        self.stop_tracking_btn.clicked.connect(self.stop_tracking_clicked.emit)
        self.stop_tracking_btn.setEnabled(False)
        layout.addWidget(self.stop_tracking_btn)
        
        # 提示标签
        self.hint_label = QLabel("请先加载视频并选择目标")
        self.hint_label.setWordWrap(True)
        self.hint_label.setStyleSheet("color: gray; font-size: 12px;")
        layout.addWidget(self.hint_label)
        
    def create_parameter_group(self):
        """
        创建参数设置组
        """
        self.parameter_group = QGroupBox("算法参数")
        layout = QGridLayout(self.parameter_group)
        
        # 相似度阈值
        layout.addWidget(QLabel("相似度阈值:"), 0, 0)
        self.similarity_threshold_slider = QSlider(Qt.Horizontal)
        self.similarity_threshold_slider.setRange(10, 90)
        self.similarity_threshold_slider.setValue(30)
        self.similarity_threshold_slider.valueChanged.connect(self.on_parameter_changed)
        layout.addWidget(self.similarity_threshold_slider, 0, 1)
        
        self.similarity_threshold_label = QLabel("0.30")
        layout.addWidget(self.similarity_threshold_label, 0, 2)
        
        # 最大丢失帧数
        layout.addWidget(QLabel("最大丢失帧数:"), 1, 0)
        self.max_lost_frames_spinbox = QSpinBox()
        self.max_lost_frames_spinbox.setRange(1, 50)
        self.max_lost_frames_spinbox.setValue(10)
        self.max_lost_frames_spinbox.valueChanged.connect(self.on_parameter_changed)
        layout.addWidget(self.max_lost_frames_spinbox, 1, 1, 1, 2)
        
        # Kalman权重
        layout.addWidget(QLabel("Kalman权重:"), 2, 0)
        self.kalman_weight_slider = QSlider(Qt.Horizontal)
        self.kalman_weight_slider.setRange(10, 90)
        self.kalman_weight_slider.setValue(30)
        self.kalman_weight_slider.valueChanged.connect(self.on_parameter_changed)
        layout.addWidget(self.kalman_weight_slider, 2, 1)
        
        self.kalman_weight_label = QLabel("0.30")
        layout.addWidget(self.kalman_weight_label, 2, 2)
        
        # 重置按钮
        self.reset_params_btn = QPushButton("重置参数")
        self.reset_params_btn.clicked.connect(self.reset_parameters)
        layout.addWidget(self.reset_params_btn, 3, 0, 1, 3)
        
    def create_info_group(self):
        """
        创建信息显示组
        """
        self.info_group = QGroupBox("跟踪信息")
        layout = QVBoxLayout(self.info_group)
        
        # 创建信息标签
        self.frame_count_label = QLabel("帧数: 0")
        self.success_rate_label = QLabel("成功率: 0%")
        self.tracking_status_label = QLabel("状态: 未开始")
        self.fps_label = QLabel("FPS: 0")
        
        # 添加到布局
        layout.addWidget(self.frame_count_label)
        layout.addWidget(self.success_rate_label)
        layout.addWidget(self.tracking_status_label)
        layout.addWidget(self.fps_label)
        
    def on_parameter_changed(self):
        """
        参数变化回调
        """
        # 获取当前参数值
        similarity_threshold = self.similarity_threshold_slider.value() / 100.0
        max_lost_frames = self.max_lost_frames_spinbox.value()
        kalman_weight = self.kalman_weight_slider.value() / 100.0
        
        # 更新标签显示
        self.similarity_threshold_label.setText(f"{similarity_threshold:.2f}")
        self.kalman_weight_label.setText(f"{kalman_weight:.2f}")
        
        # 发送参数变化信号
        params = {
            'similarity_threshold': similarity_threshold,
            'max_lost_frames': max_lost_frames,
            'kalman_weight': kalman_weight
        }
        self.parameters_changed.emit(params)
        
    def reset_parameters(self):
        """
        重置参数到默认值
        """
        self.similarity_threshold_slider.setValue(int(self.default_params['similarity_threshold'] * 100))
        self.max_lost_frames_spinbox.setValue(self.default_params['max_lost_frames'])
        self.kalman_weight_slider.setValue(int(self.default_params['kalman_weight'] * 100))
        
    def update_video_info(self, video_info: Dict):
        """
        更新视频信息显示
        
        参数：
            video_info: 视频信息字典
        """
        info_text = f"尺寸: {video_info['width']}x{video_info['height']}\n"
        info_text += f"帧率: {video_info['fps']:.1f}fps\n"
        info_text += f"总帧数: {video_info['frame_count']}\n"
        info_text += f"时长: {video_info['duration']:.1f}s"
        
        self.video_info_label.setText(info_text)
        self.play_pause_btn.setEnabled(True)
        
    def update_tracking_info(self, tracking_info: Dict):
        """
        更新跟踪信息显示
        
        参数：
            tracking_info: 跟踪信息字典
        """
        if 'frame_count' in tracking_info:
            self.frame_count_label.setText(f"帧数: {tracking_info['frame_count']}")
            
        if 'success_rate' in tracking_info:
            self.success_rate_label.setText(f"成功率: {tracking_info['success_rate']:.1%}")
            
        if 'is_tracking' in tracking_info:
            status = "跟踪中" if tracking_info['is_tracking'] else "跟踪失败"
            self.tracking_status_label.setText(f"状态: {status}")
            
        if 'fps' in tracking_info:
            self.fps_label.setText(f"FPS: {tracking_info['fps']:.1f}")
            
    def enable_tracking_controls(self, enabled: bool):
        """
        启用/禁用跟踪控制
        
        参数：
            enabled: 是否启用
        """
        self.start_tracking_btn.setEnabled(enabled)
        
        if enabled:
            self.hint_label.setText("目标已选择，可以开始跟踪")
        else:
            self.hint_label.setText("请先加载视频并选择目标")
            
    def set_tracking_state(self, is_tracking: bool):
        """
        设置跟踪状态
        
        参数：
            is_tracking: 是否正在跟踪
        """
        self.start_tracking_btn.setEnabled(not is_tracking)
        self.stop_tracking_btn.setEnabled(is_tracking)
        
        if is_tracking:
            self.hint_label.setText("正在跟踪中...")
        else:
            self.hint_label.setText("跟踪已停止")
            
    def reset(self):
        """
        重置控制面板状态
        """
        # 重置按钮状态
        self.start_tracking_btn.setEnabled(False)
        self.stop_tracking_btn.setEnabled(False)
        self.play_pause_btn.setEnabled(False)
        
        # 重置信息显示
        self.video_info_label.setText("未加载视频")
        self.frame_count_label.setText("帧数: 0")
        self.success_rate_label.setText("成功率: 0%")
        self.tracking_status_label.setText("状态: 未开始")
        self.fps_label.setText("FPS: 0")
        
        # 重置提示
        self.hint_label.setText("请先加载视频并选择目标")
        
    def get_current_parameters(self) -> Dict:
        """
        获取当前参数设置
        
        返回：
            参数字典
        """
        return {
            'similarity_threshold': self.similarity_threshold_slider.value() / 100.0,
            'max_lost_frames': self.max_lost_frames_spinbox.value(),
            'kalman_weight': self.kalman_weight_slider.value() / 100.0
        } 